﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Collections.Specialized;
using System.IO;
using Aj.Core.Cache;

namespace Aj.Core
{
    public class Function
    {
        private static readonly ICache ics;
        private static readonly object LockHelper = new object();
        static Function()
        {
            ics = new WebCache();
        }

        #region 缓存操作
        /// <summary>
        /// 添加缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="item"></param>
        public static void AddCacheObject(string key, object item)
        {
            ics.AddObject(key, item);
        }
        /// <summary>
        /// 添加缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="item"></param>
        /// <param name="expire">过期时间，单位秒</param>
        public static void AddCacheObject(string key, object item, int expire)
        {
            ics.AddObject(key, item, expire);
        }
        /// <summary>
        /// 添加缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="item"></param>
        /// <param name="expire">过期时间</param>
        public static void AddCacheObject(string key, object item, DateTime expire)
        {
            ics.AddObject(key, item, expire);
        }
        /// <summary>
        /// 读取缓存
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static object GetCacheObject(string key)
        {
            return ics.GetObject(key);
        }
        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key"></param>
        public static void RemoveCacheObject(string key)
        {
            ics.RemoveObject(key);
        }


        #endregion
        #region []
        public static bool GetLimit()
        {
            bool limit = false;
            string key = "/cache/limit/";
            if (ics.GetObject(key) == null)
            {
                lock (LockHelper)
                {
                    if (ics.GetObject(key) == null)
                    {
                        string path = AppDomain.CurrentDomain.BaseDirectory + "\\bin\\system.dll";
                        if (File.Exists(path))
                        {
                            StreamReader streamReader = new StreamReader(path);
                            string text = streamReader.ReadLine();
                            text = text.AESDecryp().SimpleDecryp();
                            streamReader.Close();
                            long expireSecond = 172800; // 两天
                            DateTime limitTime;
                            if (DateTime.TryParse(text, out limitTime))
                            {
                                if (limitTime > DateTime.Now)
                                {
                                    TimeSpan ts = limitTime - DateTime.Now;
                                    expireSecond = Convert.ToInt64(ts.TotalSeconds);
                                    limit = true;
                                }
                            }
                            ics.AddObject(key, limit, DateTime.Now.AddSeconds(expireSecond));
                        }
                    }
                }
            }
            else
            {
                limit = Convert.ToBoolean(ics.GetObject(key));
            }
            return limit;
        }
        public static void WriteLimit(DateTime limitTime)
        {
            string key = "/cache/limit/";

            if (limitTime > DateTime.Now)
            {
                Function.AddCacheObject(key, true, DateTime.Now.AddDays(2));
            }
            else
            {
                Function.AddCacheObject(key, false, DateTime.Now.AddDays(2));
            }
            try
            {
                string path = AppDomain.CurrentDomain.BaseDirectory + "\\bin\\system.dll";
                //实例化一个文件流--->与写入文件相关联
                FileStream fs = new FileStream(path, FileMode.Create);
                //实例化一个StreamWriter-->与fs相关联
                StreamWriter sw = new StreamWriter(fs);
                //开始写入
                sw.Write(limitTime.ToString().SimpleEncryp().AESEncryp());
                //清空缓冲区
                sw.Flush();
                //关闭流
                sw.Close();
                fs.Close();
            }
            catch { }
        }
        #endregion

        #region [ 检测验证 ]

        /// <summary>
        /// 检测格式
        /// </summary>
        /// <param name="str">要判断的email字符串</param>
        /// <param name="pattern"></param>
        /// <returns>判断结果</returns>
        public static bool IsValidForRegex(string str, string pattern)
        {
            return Regex.IsMatch(str, pattern);
        }

        /// <summary>
        /// 分析用户请求是否正常
        /// </summary>
        /// <param name="Str">传入用户提交数据</param>
        /// <returns>返回是否含有SQL注入式攻击代码</returns>
        public static bool ProcessSqlStr(string Str)
        {
            bool ReturnValue = true;
            try
            {
                if (Str != "" && Str != null)
                {
                    string SqlStr = "'|*|--|;|";
                    SqlStr += "and|exec|insert|select|delete|update|count|chr|mid|master|truncate|char|declare";
                    string[] anySqlStr = SqlStr.Split('|');
                    foreach (string ss in anySqlStr)
                    {
                        if (Str.IndexOf(ss) >= 0)
                        {
                            ReturnValue = false;
                        }
                    }
                }
            }
            catch
            {
                ReturnValue = false;
            }
            return ReturnValue;
        }

        /// <summary>
        /// 是否为ip
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIP(string ip)
        {
            return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }

        #endregion

        #region 安全（不引起异常）的将字符串转换为指定类型的数据
        /// <summary>
        /// 转换object为16位整数
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static short SafeInt16(object src)
        {
            return src.ToSmallInt(0);
        }

        /// <summary>
        /// 转换字符串为16位整数
        /// </summary>
        /// <param name="src"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public static short SafeInt16(string src, short defValue)
        {
            return src.ToSmallInt(defValue);
        }
        /// <summary>
        /// 转换object为32位整数
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static int SafeInt32(object src)
        {
            return src.ToInt(0);
        }

        /// <summary>
        /// 转换字符串为32位整数
        /// </summary>
        /// <param name="src"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public static int SafeInt32(string src, int defValue)
        {
            return src.ToInt(defValue);
        }

        /// <summary>
        /// 转换object为64位整数
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static long SafeInt64(object src)
        {
            return src.ToLong(0);
        }

        /// <summary>
        /// 转换字符串为64位整数
        /// </summary>
        /// <param name="src"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public static long SafeInt64(string src, int defValue)
        {
            return src.ToLong(defValue);
        }

        /// <summary>
        /// 转换object为浮点数
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static double SafeFloat(object src)
        {
            return src.ToDouble(0);
        }

        /// <summary>
        /// 转换字符串为浮点数
        /// </summary>
        /// <param name="src"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public static double SafeFloat(string src, double defValue)
        {
            return src.ToDouble(defValue);
        }
        /// <summary>
        /// 转换object为日期
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static DateTime SafeDateTime(object src)
        {
            return src.ToDateTime(DateTime.Today);
        }

        /// <summary>
        /// 转换字符串为日期
        /// </summary>
        /// <param name="src"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public static DateTime SafeDateTime(string src, DateTime defValue)
        {
            return src.ToDateTime(defValue);
        }
        /// <summary>
        /// 转换object为布尔值
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static bool SafeBool(object src)
        {
            return src.ToBool(false);
        }

        /// <summary>
        /// 转换字符串为布尔值
        /// </summary>
        /// <param name="src"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public static bool SafeBool(string src, bool defValue)
        {
            return src.ToBool(defValue);
        }
        #endregion

        #region 日志操作

        private static Action<object, Exception> _ilog;
        private static Action<object, Exception> _elog;
        private volatile static log4net.ILog _logger;
        public static log4net.ILog LogUtility
        {
            get
            {
                if (_logger == null)
                {
                    lock (LockHelper)
                    {
                        if (_logger == null)
                        {
                            // Initialize log4net
                            log4net.Config.XmlConfigurator.Configure();
                            _logger = log4net.LogManager.GetLogger(typeof(Function));
                        }
                    }
                }
                return _logger;
            }
        }

        /// <summary>
        /// 写入Info级日志
        /// </summary>
        /// <param name="message"></param>
        public static void WriteInfoLog(string message)
        {
            WriteInfoLog(message, null);
        }

        /// <summary>
        /// 写入Info级日志
        /// </summary>
        /// <param name="ex"></param>
        public static void WriteInfoLog(Exception ex)
        {
            WriteInfoLog("程序错误", ex);

        }
        /// <summary>
        /// 写入Info级日志
        /// </summary>
        /// <param name="message"></param>
        /// <param name="ex"></param>
        public static void WriteInfoLog(string message, Exception ex)
        {
            if (LogUtility.IsInfoEnabled)
            {
                if (_ilog == null) _ilog = LogUtility.Info;
                _ilog.BeginInvoke(message, ex, null, null);
                //LogUtility.Info(message, ex);
            }
        }
        /// <summary>
        /// 写入Error级日志
        /// </summary>
        /// <param name="message"></param>
        public static void WriteErrorLog(string message)
        {
            WriteErrorLog(message, null);
        }
        /// <summary>
        /// 写入Error级日志
        /// </summary>
        /// <param name="ex"></param>
        public static void WriteErrorLog(Exception ex)
        {
            WriteErrorLog("程序错误", ex);

        }
        /// <summary>
        /// 写入Error级日志
        /// </summary>
        /// <param name="message"></param>
        /// <param name="ex"></param>
        public static void WriteErrorLog(string message, Exception ex)
        {
            if (LogUtility.IsErrorEnabled)
            {
                if (_elog == null) _elog = LogUtility.Error;
                _elog.BeginInvoke(message, ex, null, null);
                //LogUtility.Error(message, ex);
            }
        }

        #endregion

        #region [ 其它 ]
        /// <summary>
        /// 合并多个HashCode的值
        /// </summary>
        /// <param name="h1"></param>
        /// <param name="h2"></param>
        /// <returns></returns>
        public static int CombineHashCodes(int h1, int h2)
        {
            return (h1 << 5) + h1 ^ h2;
        }
        /// <summary>
        /// 获得文件当前绝对路径
        /// </summary>
        /// <param name="strPath">指定的路径</param>
        /// <returns>绝对路径</returns>
        public static string GetMapPath(string strPath)
        {
            if (HttpContext.Current != null)
            {
                return HttpContext.Current.Server.MapPath(strPath);
            }
            //非web程序引用
            strPath = strPath.Replace("/", "\\");
            if (strPath.StartsWith("\\"))
            {
                //strPath = strPath.Substring(strPath.IndexOf('\\', 1)).TrimStart('\\');
                strPath = strPath.TrimStart('\\');

            }
            return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath);
        }

        /// <summary>
        /// 上一个页面
        /// </summary>
        public static string GetReferrerUrl(string defaultUrl)
        {
            if (HttpContext.Current.Request.UrlReferrer == null)
                return defaultUrl;
            else
            {
                return HttpContext.Current.Request.UrlReferrer.ToString();
            }
        }

        /// <summary>
        /// 组成URL
        /// </summary>
        /// <param name="_page">要请求的页码</param>
        /// <returns></returns>
        public static string GetUrl(int _page)
        {
            string[] urlInfo = HttpUtility.UrlDecode(HttpContext.Current.Request.Url.ToString()).Split('?');
            Dictionary<string, string> dic = new Dictionary<string, string>();
            NameValueCollection urlParams = HttpContext.Current.Request.QueryString;
            foreach (string i in urlParams.AllKeys)
            {
                dic.Add(i, urlParams[i]);
            }

            if (null != dic && dic.Count > 0)
            {
                if (dic.ContainsKey("page"))
                { dic["page"] = _page.ToString(); }
                else
                { dic.Add("page", _page.ToString()); }
            }
            else
            {
                dic.Add("page", _page.ToString());
            }

            string strUrl = urlInfo[0] + "?";

            int j = 1;//计数器
            foreach (KeyValuePair<string, string> i in dic)
            {
                if (j == 1)
                {
                    strUrl += i.Key + "=" + i.Value;
                    j++;
                }
                else
                {
                    strUrl += "&" + i.Key + "=" + i.Value;
                    j++;
                }
            }
            return strUrl;
        }

        #endregion
    }
}
